/*!
* Validator v0.11.5 for Bootstrap 3, by @1000hz
* Copyright 2016 Cina Saffary
* Licensed under http://opensource.org/licenses/MIT
*
* https://github.com/1000hz/bootstrap-validator
*/+function($){'use strict';function getValue($el){return $el.is('[type="checkbox"]')?$el.prop('checked'):$el.is('[type="radio"]')?!!$('[name="'+$el.attr('name')+'"]:checked').length:$el.val()}
var Validator=function(element,options){this.options=options
this.validators=$.extend({},Validator.VALIDATORS,options.custom)
this.$element=$(element)
this.$btn=$('button[type="submit"], input[type="submit"]').filter('[form="'+this.$element.attr('id')+'"]').add(this.$element.find('input[type="submit"], button[type="submit"]'))
this.update()
this.$element.on('input.bs.validator change.bs.validator focusout.bs.validator',$.proxy(this.onInput,this))
this.$element.on('submit.bs.validator',$.proxy(this.onSubmit,this))
this.$element.on('reset.bs.validator',$.proxy(this.reset,this))
this.$element.find('[data-match]').each(function(){var $this=$(this)
var target=$this.data('match')
$(target).on('input.bs.validator',function(e){getValue($this)&&$this.trigger('input.bs.validator')})})
this.$inputs.filter(function(){return getValue($(this))}).trigger('focusout')
this.$element.attr('novalidate',true)
this.toggleSubmit()}
Validator.VERSION='0.11.5'
Validator.INPUT_SELECTOR=':input:not([type="hidden"], [type="submit"], [type="reset"], button)'
Validator.FOCUS_OFFSET=20
Validator.DEFAULTS={delay:500,html:false,disable:true,focus:true,custom:{},errors:{match:'Does not match',minlength:'Not long enough'},feedback:{success:'glyphicon-ok',error:'glyphicon-remove'}}
Validator.VALIDATORS={'native':function($el){var el=$el[0]
if(el.checkValidity){return!el.checkValidity()&&!el.validity.valid&&(el.validationMessage||"error!")}},'match':function($el){var target=$el.data('match')
return $el.val()!==$(target).val()&&Validator.DEFAULTS.errors.match},'minlength':function($el){var minlength=$el.data('minlength')
return $el.val().length<minlength&&Validator.DEFAULTS.errors.minlength}}
Validator.prototype.update=function(){this.$inputs=this.$element.find(Validator.INPUT_SELECTOR).add(this.$element.find('[data-validate="true"]')).not(this.$element.find('[data-validate="false"]'))
return this}
Validator.prototype.onInput=function(e){var self=this
var $el=$(e.target)
var deferErrors=e.type!=='focusout'
if(!this.$inputs.is($el))return
this.validateInput($el,deferErrors).done(function(){self.toggleSubmit()})}
Validator.prototype.validateInput=function($el,deferErrors){var value=getValue($el)
var prevErrors=$el.data('bs.validator.errors')
var errors
if($el.is('[type="radio"]'))$el=this.$element.find('input[name="'+$el.attr('name')+'"]')
var e=$.Event('validate.bs.validator',{relatedTarget:$el[0]})
this.$element.trigger(e)
if(e.isDefaultPrevented())return
var self=this
return this.runValidators($el).done(function(errors){$el.data('bs.validator.errors',errors)
errors.length?deferErrors?self.defer($el,self.showErrors):self.showErrors($el):self.clearErrors($el)
if(!prevErrors||errors.toString()!==prevErrors.toString()){e=errors.length?$.Event('invalid.bs.validator',{relatedTarget:$el[0],detail:errors}):$.Event('valid.bs.validator',{relatedTarget:$el[0],detail:prevErrors})
self.$element.trigger(e)}
self.toggleSubmit()
self.$element.trigger($.Event('validated.bs.validator',{relatedTarget:$el[0]}))})}
Validator.prototype.runValidators=function($el){var errors=[]
var deferred=$.Deferred()
$el.data('bs.validator.deferred')&&$el.data('bs.validator.deferred').reject()
$el.data('bs.validator.deferred',deferred)
function getValidatorSpecificError(key){return $el.data(key+'-error')}
function getValidityStateError(){var validity=$el[0].validity
return validity.typeMismatch?$el.data('type-error'):validity.patternMismatch?$el.data('pattern-error'):validity.stepMismatch?$el.data('step-error'):validity.rangeOverflow?$el.data('max-error'):validity.rangeUnderflow?$el.data('min-error'):validity.valueMissing?$el.data('required-error'):null}
function getGenericError(){return $el.data('error')}
function getErrorMessage(key){return getValidatorSpecificError(key)||getValidityStateError()||getGenericError()}
$.each(this.validators,$.proxy(function(key,validator){var error=null
if((getValue($el)||$el.attr('required'))&&($el.data(key)||key=='native')&&(error=validator.call(this,$el))){error=getErrorMessage(key)||error
!~errors.indexOf(error)&&errors.push(error)}},this))
if(!errors.length&&getValue($el)&&$el.data('remote')){this.defer($el,function(){var data={}
data[$el.attr('name')]=getValue($el)
$.get($el.data('remote'),data).fail(function(jqXHR,textStatus,error){errors.push(getErrorMessage('remote')||error)}).always(function(){deferred.resolve(errors)})})}else deferred.resolve(errors)
return deferred.promise()}
Validator.prototype.validate=function(){var self=this
$.when(this.$inputs.map(function(el){return self.validateInput($(this),false)})).then(function(){self.toggleSubmit()
self.focusError()})
return this}
Validator.prototype.focusError=function(){if(!this.options.focus)return
var $input=this.$element.find(".has-error:first :input")
if($input.length===0)return
$('html, body').animate({scrollTop:$input.offset().top-Validator.FOCUS_OFFSET},250)
$input.focus()}
Validator.prototype.showErrors=function($el){var method=this.options.html?'html':'text'
var errors=$el.data('bs.validator.errors')
var $group=$el.closest('.form-group')
var $block=$group.find('.help-block.with-errors')
var $feedback=$group.find('.form-control-feedback')
if(!errors.length)return
$block.data('bs.validator.originalContent')===undefined&&$block.data('bs.validator.originalContent',$block.html())
$block.empty().append(errors)
$group.addClass('has-error has-danger')
$group.hasClass('has-feedback')&&$feedback.removeClass(this.options.feedback.success)&&$feedback.addClass(this.options.feedback.error)&&$group.removeClass('has-success')}
Validator.prototype.clearErrors=function($el){var $group=$el.closest('.form-group')
var $block=$group.find('.help-block.with-errors')
var $feedback=$group.find('.form-control-feedback')
$block.html($block.data('bs.validator.originalContent'))
$group.removeClass('has-error has-danger has-success')
$group.hasClass('has-feedback')&&$feedback.removeClass(this.options.feedback.error)&&$feedback.removeClass(this.options.feedback.success)&&getValue($el)&&$feedback.addClass(this.options.feedback.success)&&$group.addClass('has-success')}
Validator.prototype.hasErrors=function(){function fieldErrors(){return!!($(this).data('bs.validator.errors')||[]).length}
return!!this.$inputs.filter(fieldErrors).length}
Validator.prototype.isIncomplete=function(){function fieldIncomplete(){var value=getValue($(this))
return!(typeof value=="string"?$.trim(value):value)}
return!!this.$inputs.filter('[required]').filter(fieldIncomplete).length}
Validator.prototype.onSubmit=function(e){this.validate()
if(this.isIncomplete()||this.hasErrors())e.preventDefault()}
Validator.prototype.toggleSubmit=function(){if(!this.options.disable)return
this.$btn.toggleClass('disabled',this.isIncomplete()||this.hasErrors())}
Validator.prototype.defer=function($el,callback){callback=$.proxy(callback,this,$el)
if(!this.options.delay)return callback()
window.clearTimeout($el.data('bs.validator.timeout'))
$el.data('bs.validator.timeout',window.setTimeout(callback,this.options.delay))}
Validator.prototype.reset=function(){this.$element.find('.form-control-feedback').removeClass(this.options.feedback.error).removeClass(this.options.feedback.success)
this.$inputs.removeData(['bs.validator.errors','bs.validator.deferred']).each(function(){var $this=$(this)
var timeout=$this.data('bs.validator.timeout')
window.clearTimeout(timeout)&&$this.removeData('bs.validator.timeout')})
this.$element.find('.help-block.with-errors').each(function(){var $this=$(this)
var originalContent=$this.data('bs.validator.originalContent')
$this.removeData('bs.validator.originalContent').html(originalContent)})
this.$btn.removeClass('disabled')
this.$element.find('.has-error, .has-danger, .has-success').removeClass('has-error has-danger has-success')
return this}
Validator.prototype.destroy=function(){this.reset()
this.$element.removeAttr('novalidate').removeData('bs.validator').off('.bs.validator')
this.$inputs.off('.bs.validator')
this.options=null
this.validators=null
this.$element=null
this.$btn=null
return this}
function Plugin(option){return this.each(function(){var $this=$(this)
var options=$.extend({},Validator.DEFAULTS,$this.data(),typeof option=='object'&&option)
var data=$this.data('bs.validator')
if(!data&&option=='destroy')return
if(!data)$this.data('bs.validator',(data=new Validator(this,options)))
if(typeof option=='string')data[option]()})}
var old=$.fn.validator
$.fn.validator=Plugin
$.fn.validator.Constructor=Validator
$.fn.validator.noConflict=function(){$.fn.validator=old
return this}
$(window).on('load',function(){$('form[data-toggle="validator"]').each(function(){var $form=$(this)
Plugin.call($form,$form.data())})})}(jQuery);